3.开始设备端开发
上传设备信息
当我们完成了设备描述信息文件,也就是xml文件的编写
swaylink系统几乎都使用http协议的post方式发送信息。
本质上,就是用TCP socket向服务器发送一段字符串。字符编码格式统一采用utf8格式,
对于该接口,需要发送以下形式的字符串:
POST /swaylink.php?m=Queen&c=Upload&a=devInfoUpload HTTP/1.1\r\n
Host:www.swaylink.cn\r\n
Content-Type:application/x-www-form-urlencoded\r\n;
Content-Length:XX\r\n
v=2.0&dev_id=guid1&token=guid2_timestamp&load=XXXXXXXXX
其中:
Content-Length:XX\r\n
xx表示http报文中数据段的长度,是从
v=2.0&dev_id=guid1&token=xxxxxx&load=XXXXXXXXX
开始计算长度的。
也就是我们发送的数据,以后说的“POST数据”就是指这部分内容。
v=2.0&dev_id=guid1&token=xxxxxxx&load=xxxxxxxx
其中,v表示为协议版本号;guid1就是dev_id也就是前面申请的设备号;token就是身份令牌,服务器只有检测身份令牌通过只有才回接收上传数据,下面会讲解token生成的方法。load就是要上传的xml字符串。token是一串加密后的字符串。字符串原文是guid2_timestamp,就是guid2(如下图所示))拼接下划线拼接10位时间戳(没有时间戳可以是长度为10的随机数或者字符串);加密算法采用的时候AES128,选用的是ECB模式,加密密钥key登录官网在用户界面就能看到(如下图)。具体流程为,组织原文guid2_timestamp,然后用自己的秘钥,每个设备都有一个唯一的秘钥key(请妥善保管)进行AES128,最后进行base64进行编码,得到的结果就是我们需要的token。可以参考下面部分语言示例代码。
下面是php 加密解密示例
/**
* AES加密
* @param string key 加密秘钥
* @param string guid2 加密的guid2值
* @return string 加密后的密文
*/
public static function aesEncode($key,$guid2){
$guid2 .= '_'.time();
//加密方式 aes128
$CIPHER = MCRYPT_RIJNDAEL_128;
//ECB模式
$MODE = MCRYPT_MODE_ECB;
$iv = mcrypt_create_iv(mcrypt_get_iv_size($CIPHER, $MODE), MCRYPT_RAND);
$out_str = mcrypt_encrypt($CIPHER, $key, $guid2, $MODE, $iv);
return base64_encode($out_str);
}
/**
* AES解密
* @param string str 加密后的密文
* @param string key 加密秘钥
* @return string 原文
*/
public static function aesDecode($str, $key){
//base64还原
$string = base64_decode($str);
//加密方式
$CIPHER = MCRYPT_RIJNDAEL_128;
//ECB模式
$MODE = MCRYPT_MODE_ECB;
$iv = mcrypt_create_iv(mcrypt_get_iv_size($CIPHER, $MODE), MCRYPT_RAND);
return mcrypt_decrypt($CIPHER, $key, $string, $MODE, $iv);
}
http实现发送以上字符串的C语言代码如下所示。
// C 语言程序
char xml_str[] = "XXXXXXXXXXXXXXX"; // xml文件内容
char post_data_str[] = "";
// 请用你的guid1、guid2和token戳替换
sprintf( post_data_str, "v=2.0&dev_id=guid1&token=xxxxx&load=%s", xml_str );
char http_str[] = "POST /swaylink.php?m=Queen&c=Upload&a=devInfoUpload HTTP/1.1\r\n";
strcat( http_str, "Host:www.swaylink.cn\r\n");
strcat( http_str, "Content-Type:application/x-www-form-urlencoded\r\n");
sprintf( http_str, "Content-Length:%d\r\n\r\n", strlen(post_data_str) );
strcat( http_str, post_data_str );
// 通过socket将http_str发送到www.swaylink.cn的80端口
Python3程序如下所示。
import urllib.request,urllib.parse
import time
# 请用你自己的guid1/2值替换
guid1 = 'XXXX'
guid2 = 'YYYY'
url = 'www.swaylink.cn?m=Queen&c=Upload&a=devInfoUpload'
post_data = {'v':'2.0','dev_id':guid1,'token':guid2+'_'+str(time.time()),'load':xml_str}
upload( url, post_data )
def upload(url,post_data):
pdata = urllib.parse.urlencode( post_data )
pdata = pdata.encode(encoding='utf-8',errors='ignore')
header = { 'User-Agent':'swaylink-dev/2.0 (python3.4; Trident/7.0; rv:11.0)' }
req = urllib.request.Request(url=url, data=pdata, headers=header, method='POST')
try:
res = urllib.request.urlopen( req, timeout=5 )
except Exception as e:
print( 'Reason: ', e )
return ''
return res.read().decode('utf-8-sig')
上传数值型数据
该接口地址为: swaylink.php?m=Queen&c=Upload&a=num
POST数据格式为:v=2.0&dev_id=guid1&token=guid2_timestamp&load=data_json_str
其中data_json_str
为JSON字符串形式的设备参数。其组织如下所示:
[
// 设备1的数据
{
"dev_id":guid1,
"data":[{参数1信息},{参数2信息},…{参数n信息}]
}
// 设备2的数据
{…}
]
// 其中{参数n}信息为:
{
"id":n, // 代表参数的id
"v":[0.5,0.7,1.0,2.0], // 参数值
"t":[142040556,+1,-1,+2] // 对应每个参数值的UTC时间戳
// t[0]为基准时间戳,以后的t信息皆以与基时间戳的增量方式存储
// 即该例中,原始的t时间戳为:
// 142040556,142040557,142040555,142040558
}
同样的,发送以下字符串至www.swaylink.cn的80端口,就完成了设备数据的上传。
POST /swaylink.php?m=Queen&c=Upload&a=num HTTP/1.1\r\n
Host:www.swaylink.cn\r\n
Content-Type:application/x-www-form-urlencoded\r\n
Content-Length:XX\r\n
\r\n
v=2.0&dev_id=guid1&token=guid2_timestamp&load=data_json_str